/*******************************************************************************
    文件名称： 
	开发者：孙磊
	开发时间地点：2013.12.27 
	邮箱：zhongyuansunlei@163.com
	版本信息：
		
********************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "common.h"
#include "strutil.h"
#include "http.h"




#define	HTTP_LFCR	"\r\n"


int ihttp_connect(char* pip, int iport)
{
	int ifd, irtn;
	socklen_t	olen;
	struct sockaddr_in	oservaddr;
	
	ifd = socket(AF_INET, SOCK_STREAM, 0);
	if(-1 == ifd)
	{
		printf("socket error");
		return -1;
	}
	
	memset(&oservaddr, 0, sizeof(oservaddr));
	oservaddr.sin_family = AF_INET;
	oservaddr.sin_addr.s_addr = inet_addr(pip);
	oservaddr.sin_port = htons(iport);
	olen = sizeof(oservaddr);
	irtn = connect(ifd, (struct sockaddr*)&oservaddr, olen);     
	if(-1 == irtn)
	{
  		printf("conncet error");
		return -1;      
	}
	
	return ifd;
}


int ihttp_send(int ifd, char* pres, httpinfo *phttpinfo)
{
	char shttp[TWO_K_SIZE], sline[QUART_K_SIZE];
	int irtn;
	
	memset(shttp,0,TWO_K_SIZE);
	memset(sline,0,QUART_K_SIZE);
	
	sprintf(sline, "GET %s HTTP/1.1%s", pres, HTTP_LFCR);
	strcat(shttp, sline);
	
	sprintf(sline, "Accept: */*%s", HTTP_LFCR);
	strcat(shttp, sline);
	
	//sprintf(sline, "Accept-Encoding:gzip,deflate%s", HTTP_LFCR);
	//strcat(shttp, sline);
	
	//sprintf(sline, "User-Agent: Mozilla/4.0 (compatible; MSIE 4.0; Windows NT)%s", HTTP_LFCR);
	//strcat(shttp, sline);
	
	sprintf(sline, "Host: %s%s", phttpinfo->m_sdns, HTTP_LFCR);
	strcat(shttp, sline);
	
	sprintf(sline, "Connection: Keep-Alive%s%s", HTTP_LFCR,HTTP_LFCR);
	strcat(shttp, sline);
	
	//printf("shttp=:\n%s", shttp);
	
	return write(ifd, shttp, strlen(shttp));
}


int isock_read_symbol(int ifd, char*pbuf, char* psymbol)
{
	int inum, i,j;
	char* p = pbuf;
	i = j = 0;
	inum = strlen(psymbol);
	while(true) {
		if((j=read(ifd, p+i, 1)) == -1) {
			if(errno != EAGAIN) {
				printf("read error , errnor = %d\n", errno);
				return -1;
			}
		} else if(j>0) {
			i++;
		} 
		
		if(i>=inum) {
			if(!strncmp(p+i-inum, psymbol, inum))
				break;
		}
	}

	*(p+i) = 0;
	
	return i;
}
/*
	以后要支持解压gzip 等 以及chunk等

*/
int ihttp_rcv(int ifd, char**pbuff, int *pbufsize, resinfo* presinfo)
{
	char* p, *s, *t;
	int inum,ileft, irtn;
	long lcode,llength;
	char smsg[FOUR_UNIT_SIZE];
	
	p = *pbuff;
	
	while(1) {
		inum = isock_read_symbol(ifd, p, HTTP_LFCR);
		if(inum > 2) {
			
		} else if(inum == 2) {
			if((lcode != 100)&&(lcode != 200)) {
				return -1;
			} else {
				p+=inum;
				break;
			}
		} else {
			return -1;
		}
		
		if((s = strstr(p, "HTTP"))!= NULL) {
			if((t = strstr(s, " ")) != NULL)
			{
				sscanf(t, " %ld %s", &lcode, smsg);
				if(200 != lcode && 100 != lcode)
				{
					return -1;
				}
			}
		} else if((s = strstr(p, "Content-Length"))!= NULL) {
			if((t = strstr(s, ":")) != NULL)
			{
				sscanf(t+1, "%ld", &llength);
			}
		}
		p+=inum;
	}
	
	p = *pbuff;
	if(*pbufsize < llength) {
		p = (char*)malloc(llength+1);
		if(p==NULL)
			return -1;
		*pbufsize = llength;
	}
	
	ileft = llength;
	while(1) {
		irtn = read(ifd, p, ileft);
		if(irtn == -1) {
			if(errno != EAGAIN) {
				printf("read error , errnor = %d\n", errno);
				return -1;
			}
		} else if(irtn > 0){
			p+=irtn;
			ileft-=irtn;
		} else if(irtn == 0) {
			break;
		}
	}
	p = *pbuff;
	*(p+llength-ileft) = '\0';
   return llength-ileft;
}


int ihttp_close(int ifd)
{
	return close(ifd);
}



int ifile_archive(char* pdir, char* purl, char* pbuffer, int isize)
{
	char sfile[QUART_K_SIZE], sfullfile[K_SIZE];
	int ifd;
	memset(sfile, 0, QUART_K_SIZE);
	memset(sfullfile, 0, K_SIZE);
	
	if(istr_replace(purl, sfile, '/', '_')) {
		return -1;
	}
	
	snprintf(sfullfile, sizeof(sfullfile), "%s/%s", pdir, sfile);
	
	if((ifd = open(sfullfile, O_RDWR|O_CREAT|O_TRUNC)) == -1) {
		printf("open file error, errno = %d", errno);
		return -1;
	}
	
	if(write(ifd, pbuffer, isize) == -1) {
		printf("write file error, errno = %d", errno);
		return -1;
	}
	
	close(ifd);
	
	return 0;
	
}
